package com.aion.jirc.gui;

import com.aion.jirc.irc.IRCConnection;
import com.aion.jirc.util.Colors;
import com.aion.jirc.util.IRCStringUtils;

import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * Date: 11-01-29
 * Time: 15:07
 *
 * @author Aion
 * @author Zippy
 */
public class ClientGUI extends JFrame implements ActionListener, KeyListener {

    private static final String NETWORK = "strictfp";
    private static final int DEFAULT_PORT = 6667;
    private static final String SERVER = "irc.strictfp.com";

    private static final int WIDTH_OFFSET = 8;
    private static final int HEIGHT_OFFSET = 95;

    private JDesktopPane desktop;

    private Switchbar switchbar;
    private Menubar menubar;
    private Toolbar toolbar;

    private Vector<Window> windows;
    private StatusWindow statusWindow;

    IRCConnection irc;

    public ClientGUI() {
        this("JIRC");
    }

    public ClientGUI(String title) {
        super(title);
        init();
        setLocationRelativeTo(getOwner());
        setResizable(true);
    }

    public int getDefaultPort() {
        return DEFAULT_PORT;
    }

    public String getNetwork() {
        return NETWORK;
    }

    public String getServer() {
        return SERVER;
    }

    private void init() {
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int status = JOptionPane.showConfirmDialog(
                        null,
                        "Are you sure you want to exit JIRC?",
                        "Confirm exit",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.WARNING_MESSAGE);
                if (status == 0) {
                    dispose();
                    System.exit(0);
                }
            }
        });

        setSize(600, 450);
        setPreferredSize(new Dimension(600,450));

        JPopupMenu.setDefaultLightWeightPopupEnabled(false);

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ignored) { }

        windows = new Vector<Window>();

        menubar = new Menubar(this);
        setJMenuBar(menubar);

        toolbar = new Toolbar(this);
        add(toolbar, BorderLayout.NORTH);

        switchbar = new Switchbar(this);
        switchbar.addButton("Status");
        add(switchbar, BorderLayout.SOUTH);
        desktop = new JDesktopPane();
        statusWindow = new StatusWindow(this, "Status");
        addWindow(statusWindow);
        addWindow(new ChannelWindow(this, "#Aion"));
    }

    private void addWindow(Window window) {
        //JDesktopPane desktop = new JDesktopPane();
        int width = getWidth() - WIDTH_OFFSET;
        int height = getHeight() - HEIGHT_OFFSET;
        window.setSize(width, height);
        desktop.add(window);
        windows.add(window);
        desktop.setVisible(true);
        add(desktop);
    }

    public void actionPerformed(ActionEvent e) {
        String actionCommand = e.getActionCommand();
        int index = actionCommand.indexOf(46);
        String title = actionCommand.substring(0, index);
        String element = actionCommand.substring(index + 1);
        if (title.equalsIgnoreCase("file")) {
            if (element.equalsIgnoreCase("connect")) {
                try {
                    irc = new IRCConnection(this);
                    irc.connect();
                } catch (Exception xe) { }
            } else if (element.equalsIgnoreCase("exit")) {
                dispose();
                System.exit(0);
            }
        } else if (title.equalsIgnoreCase("view")) {
            boolean selected = ((JCheckBoxMenuItem) e.getSource()).isSelected();
            if (element.equalsIgnoreCase("menubar")) {
                menubar.setVisible(selected);
            } else if (element.equalsIgnoreCase("switchbar")) {
                switchbar.setVisible(selected);
            } else if (element.equalsIgnoreCase("toolbar")) {
                toolbar.setVisible(selected);
            }
        } else if (title.equalsIgnoreCase("switchbar")) {
            for (Component c : switchbar.getComponents()) {
                if (c instanceof JButton) {
                    ((JButton) c).setSelected(c == e.getSource());
                }
            }
        } else if (title.equalsIgnoreCase("toolbar")) {
            System.out.println("OK");
            if (element.equalsIgnoreCase("connect")) {
                if (irc == null)
                try {
                    irc = new IRCConnection(this);
                    irc.connect();
                } catch (Exception xe) { }
            } else if (element.equalsIgnoreCase("disconnect")) {
                irc.disconnect();
                irc = null;
                sendLine("--------------------------------------\r\n\r\n", "");
            }
            JButton b = (JButton) e.getSource();
            b.setSelected(false);
            getStatusWindow().getOutputArea().requestFocus();
        }
    }

    public void sendLine(String line, String window) {
        Window w = getWindow(window);
        if (w == null) w = getWindow("Status");
        sendLine(line, w);
    }

    public void sendLine(String line, final Window w) {
        w.addLine(IRCStringUtils.convertToHTML(line));

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                w.getInputArea().scrollRectToVisible(new Rectangle(0, w.getInputArea().getHeight(), 1, 1));
            }
        });

    }

    /**
     * Gets a window
     * @param windowName the name of the window to get
     * @return the window associated with the given name
     */
    public Window getWindow(String windowName) {
        for (Window window : windows) {
            if (window.getWindowName().equalsIgnoreCase(windowName)) {
                return window;
            }
        }
        return getStatusWindow();
    }

    /**
     * Gets the status window.
     * @returns the status window
     */
    public StatusWindow getStatusWindow() {
        return statusWindow;
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            if ((e.getModifiersEx() & (KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)) == 0) {
                for (String line : getStatusWindow().getOutputArea().getText().split("\n")) {
                    sendLine(" -> " +line, getStatusWindow());
                    irc.getIRCHandler().send(line);
                }
                getStatusWindow().getOutputArea().setText("");
                e.consume();
            } else if ((e.getModifiersEx() & (KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)) == KeyEvent.ALT_DOWN_MASK) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + "\n");
                e.consume();
            }
        } else if ((e.getModifiersEx() & (KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)) == KeyEvent.CTRL_DOWN_MASK) {
            if (e.getKeyCode() == KeyEvent.VK_K) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + Colors.CTRL_K);
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_R) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + Colors.CTRL_R);
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_U) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + Colors.CTRL_U);
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_I) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + Colors.CTRL_I);
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_B) {
                getStatusWindow().getOutputArea().setText(getStatusWindow().getOutputArea().getText() + Colors.CTRL_B);
                e.consume();
            }
        }
    }

    public void keyReleased(KeyEvent e) {
    }

}
